---
id: file-provider
title: 31. 虚拟文件系统
sidebar_label: 31. 虚拟文件系统
---

:::important 版本说明

以下内容仅限 `Furion 2.5.0 +` 版本使用。

:::

import useBaseUrl from "@docusaurus/useBaseUrl";

## 31.1 关于文件系统

本章所谓的 `文件系统` 有点名不副实，其实根本算不上一个系统，它仅仅是利用一个抽象化的 `IFileProvider` 以统一的方式提供所需的文件而已。通过该 `文件系统` 可以读取物理文件和嵌入资源文件，包括目录结果读取，文件内容读取，文件内容监听等等。

### 31.1.1 文件系统类型

`Furion` 提供了两种文件系统类型：

- `Physical`：物理文件系统类型，也就是物理机中实际存在的文件
- `Embedded`：嵌入资源文件系统类型，也就是资源文件嵌入到了程序集中，常用于模块化开发

## 31.2 注册虚拟文件系统服务

```cs
services.AddVirtualFileServer();
```

## 31.3 获取文件系统 `IFileProvider` 实例

### 31.3.1 `Func<FileProviderTypes, object, IFileProvider>` 方式

`Furion` 框架提供了 `Func<FileProviderTypes, object, IFileProvider>` 委托供构造函数注入或解析服务，如：

```cs {6,8-9,11-12}
public class PersonServices
{
    private readonly IFileProvider _physicalFileProvider;
    private readonly IFileProvider _embeddedFileProvider;

    public PersonServices(Func<FileProviderTypes, object, IFileProvider> fileProviderResolve)
    {
        // 解析物理文件系统
        _physicalFileProvider = fileProviderResolve(FileProviderTypes.Physical, @"c:/test");

        // 解析嵌入资源文件系统
        _embeddedFileProvider = fileProviderResolve(FileProviderTypes.Embedded, Assembly.GetEntryAssembly());
    }
}
```

### 31.3.2 `FS` 静态类方式

`Furion` 框架也提供了 `FS` 静态类方式创建，如：

```cs
// 解析物理文件系统
var physicalFileProvider = FS.GetPhysicalFileProvider(@"c:/test");

// 解析嵌入资源文件系统
var embeddedFileProvider = FS.GetEmbeddedFileProvider(Assembly.GetEntryAssembly());
```

## 31.4 `IFileProvider` 常见操作

### 31.4.1 读取文件内容

```cs
byte[] buffer;
using (Stream readStream = _fileProvider.GetFileInfo("你的文件路径").CreateReadStream())
{
    buffer = new byte[readStream.Length];
    await readStream.ReadAsync(buffer.AsMemory(0, buffer.Length));
}

// 读取文件内容
var content = Encoding.UTF8.GetString(buffer);
```

### 31.4.2 获取文件目录内容（需递归查找）

```cs
var rootPath = "当前目录路径";
var fileinfos = _fileProvider.GetDirectoryContents(rootPath);
foreach (var fileinfo in fileinfos)
{
    if(fileinfo.IsDirectory)
    {
        // 这里递归。。。
    }
}
```

### 31.4.4 监听文件变化

```cs
ChangeToken.OnChange(() => _fileProvider.Watch("监听的文件"), () =>
{
    // 这里写你的逻辑
});
```

## 31.5 模块化静态资源配置

通常我们采用模块化开发，静态资源都是嵌入进程序集中，这时候我们需要通过配置 `UseFileServer` 指定模块静态资源路径，如：

```cs
// 默认静态资源调用，wwwroot
app.UseStaticFiles();

// 配置模块化静态资源
app.UseFileServer(new FileServerOptions
{
    FileProvider = new EmbeddedFileProvider(模块程序集),
    RequestPath = "/模块名称",  // 后续所有资源都是通过 /模块名称/xxx.css 调用
    EnableDirectoryBrowsing = true
});
```

## 31.6 反馈与建议

:::note 与我们交流

给 Furion 提 [Issue](https://gitee.com/dotnetchina/Furion/issues/new?issue)。

:::

---
